package com.tanhua.dubbo.api;

import cn.hutool.core.util.RandomUtil;
import com.tanhua.dubbo.api.mongo.MovementApi;
import com.tanhua.dubbo.async.TimeLineService;
import com.tanhua.dubbo.utils.IdWorker;
import com.tanhua.model.mongo.Comment;
import com.tanhua.model.mongo.Friend;
import com.tanhua.model.mongo.Movement;
import com.tanhua.model.mongo.MovementTimeLine;
import com.tanhua.model.vo.PageResult;
import org.apache.commons.lang3.RandomStringUtils;
import org.apache.commons.lang3.RandomUtils;
import org.apache.dubbo.config.annotation.DubboService;
import org.bson.types.ObjectId;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

@DubboService
public class MovementApiImpl implements MovementApi {

    @Autowired
    private MongoTemplate mongoTemplate;

    @Autowired
    private IdWorker idWorker;

    @Autowired
    private TimeLineService timeLineService;

    /**
     * 服务提供者发布动态
     * @param movement
     */
    @Override
    public void publish(Movement movement) {
        Long userId = movement.getUserId();
        long nowTime = System.currentTimeMillis();

        //1.往动态表保存动态记录
        movement.setPid(idWorker.getNextId("movement"));
        movement.setCreated(nowTime);
        mongoTemplate.insert(movement);

        //2.根据当前用户id查询好友表获取好友数据
        timeLineService.saveTimeLine(nowTime,userId,movement.getId());


//        Query query = new Query();
//        query.addCriteria(Criteria.where("userId").is(userId));
//        List<Friend> friendList = mongoTemplate.find(query, Friend.class);
//
//        //3.循环遍历好友数据，往好友时间线表插入数据
//        if(!CollectionUtils.isEmpty(friendList)){
//            for (Friend friend : friendList) {
//                MovementTimeLine movementTimeLine = new MovementTimeLine();
//                movementTimeLine.setMovementId(movement.getId());//直接从保存动态对象中获取即可
//                movementTimeLine.setUserId(userId);//发布动态的用户id
//                movementTimeLine.setFriendId(friend.getFriendId());//好友id
//                movementTimeLine.setCreated(nowTime);
//                mongoTemplate.insert(movementTimeLine);
//            }
//        }
    }


    /**
     * 分页查询动态发布表
     * @param page
     * @param pageSize
     * @param userId
     * @return
     */
    @Override
    public PageResult<Movement> findByUserId(Long page, Long pageSize, Long userId) {
        //定义返回PageResult<RecommendUser>
        PageResult<Movement> pageResult = new PageResult<>();

        Query query = new Query();
        query.addCriteria(Criteria.where("userId").is(userId));

        //1查询总记录数
        long count = mongoTemplate.count(query, Movement.class);
        // 页面起始数据
        long start = (page-1)*pageSize;

        //2查询当前页面需要展示的数据
        List<Movement> movementList = new ArrayList<>();

        if(count > start) {
            //构造分页limit 0,3
            query.limit(pageSize.intValue());
            query.skip(start);
            query.with(Sort.by(Sort.Direction.DESC,"created"));
            movementList = mongoTemplate.find(query, Movement.class);
        }

        return new PageResult<>(page,pageSize,count,movementList);
    }

    /**
     * 根据用户id查询好友时间线数据
     * @param userId
     * @param page
     * @param pageSize
     * @return
     */
    @Override
    public PageResult<Movement> findFriendMovements(Long userId, Long page, Long pageSize) {

        // 统计总数
        Query query = new Query();
        query.addCriteria(Criteria.where("userId").is(userId));
        long count = mongoTemplate.count(query, MovementTimeLine.class);

        //计算开始行
        long start = (page - 1) * pageSize;

        // 定义需要返回的结果集
        List<Movement> movementList = new ArrayList<>();

        if(count > start){
            query.skip(start).limit(pageSize.intValue());


            // 分页查询时间线表
            List<MovementTimeLine> movementTimeLineList = mongoTemplate.find(query, MovementTimeLine.class);

            // 获取时间线表对象中的所有动态id
            List<ObjectId> movementIds = movementTimeLineList.stream().map(MovementTimeLine::getMovementId).collect(Collectors.toList());
            Query momentQuery = new Query(Criteria.where("_id").in(movementIds));
            // 按照时间降序
            momentQuery.with(Sort.by(Sort.Direction.DESC,"created"));
            movementList = mongoTemplate.find(momentQuery, Movement.class);
        }
        return new PageResult<>(page,pageSize,count,movementList);
    }


    /**
     * 随机产生10个动态记录
     * @return
     */
    @Override
    public List<Movement> randomMovement() {
        Query query = new Query();
        query.with(Sort.by(Sort.Direction.DESC,"created"));
        long counts = mongoTemplate.count(query, Movement.class);
        if(counts < 10){
            return mongoTemplate.find(query,Movement.class);
        }else {
            long start = RandomUtils.nextLong(0,counts - 9);
            query.skip(start).limit(10);
            return mongoTemplate.find(query,Movement.class);
        }
    }

    /**
     * 根据推荐系统写入redis的Pids查询动态数据
     * @param listPids
     * @return
     */
    @Override
    public List<Movement> findByPids(List<Long> listPids) {
        Query query = new Query();
        query.addCriteria(Criteria.where("pid").in(listPids));
        query.with(Sort.by(Sort.Direction.DESC,"created"));
        return mongoTemplate.find(query,Movement.class);
    }

    /**
     * 根据动态id调用服务查询动态数据
     * @param movementId
     * @return
     */
    @Override
    public Movement findById1(String movementId) {
        Query query = new Query();
        query.addCriteria(Criteria.where("id").is(new ObjectId(movementId)));
        Movement movement = mongoTemplate.findOne(query, Movement.class);
        return movement;
    }
}
